---
layout: docs
page_title: Set up the key/value v2 plugin
description: >-
   Enable and configure the key/value v2 plugins to store arbitrary static
   secrets in Vault.
---

> [!IMPORTANT]  
> **Documentation Update:** Product documentation, which were located in this repository under `/website`, are now located in [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs), colocated with all other product documentation. Contributions to this content should be done in the `web-unified-docs` repo, and not this one. Changes made to `/website` content in this repo will not be reflected on the developer.hashicorp.com website.

# Set up the key/value v2 plugin

Use `vault secrets enable` to enable an instance of the `kv` plugin. To specify
version 2, use the `-version` flag or specific `kv-v2` as the plugin type:

Additionally, when running a dev-mode server, the v2 `kv` secrets engine is enabled by default at the
path `demo/` (for non-dev servers, it is currently v1). It can be disabled, moved, or enabled multiple times at
different paths. Each instance of the KV secrets engine is isolated and unique.


## Before you start 

- **You must have permission to update ACL policies**.
- **You must have permission to enable plugins**.



## Step 1: Enable the plugin


<Tabs>

<Tab heading="CLI" group="cli">

Use `vault secrets enable` to establish a new instance of the `kv` plugin.

To specify key/value version 2, use the `-version` flag or use `kv-v2` as the
plugin type.


**Option 1**: Use the `-version` flag:

```shell-session
$ vault secrets enable -path <mount_path> -version=2 kv
```

**Option 2**: Use the `kv-v2` plugin type:

```shell-session
$ vault secrets enable -path <mount_path> kv-v2
```

</Tab>

<Tab heading="GUI" group="gui">

@include 'gui-instructions/enable-secrets-plugin.mdx'

- Select the "KV" plugin.

- Enter a unique path for the plugin and provide the relevant configuration
  data.

</Tab>

<Tab heading="API" group="api">

1. Create a JSON file with the type and configuration information for your `kv`
v2 instance. Use the `options` field to set optional flags.

1. Make a `POST` call to
   [`/sys/mounts/{plugin_mount_path}`](/vault/api-docs/system/mounts#enable-secrets-engine)
   with the JSON data:
    ```shell-session
    $ curl                                      \
      --request POST                            \
      --header "X-Vault-Token: ${VAULT_TOKEN}"  \
      --data @data.json                         \
      ${VAULT_ADDR}/v1/sys/mounts/<plugin_mount_path>
    ```


For example:


<CodeBlockConfig hideClipboard="true">

```json
{
  "type": "kv",
  "options": {
    "version": "2"
  }
}
```

</CodeBlockConfig>

<CodeBlockConfig hideClipboard="true">

```shell-session
$ curl                                        \
    --request POST                            \
    --header "X-Vault-Token: ${VAULT_TOKEN}"  \
    --data @data.json                         \
    ${VAULT_ADDR}/v1/sys/mounts/shared | jq
```

</CodeBlockConfig>

`/sys/mounts/{plugin_mount_path}` does not return data on success.

</Tab>

</Tabs>



## Step 2: Create an ACL policy file

<Note>

  ACL policies for `kv` plugins do not support the `allowed_parameters`,
  `denied_parameters`, and `required_parameters` policy fields.

</Note>

Create a policy definition file based on your needs.

For example, assume there are API keys stored on the path `/dev/square-api` for
a `kv` plugin mounted at `shared/`. The following policy lets clients read and
patch the latest version of API keys and read metadata for any version of the
API keys:

```hcl
# Grants permission to read and patch the latest version of API keys
path "shared/data/dev/square-api/*" {

  capabilities = ["read", "patch"]
}

# Grants permission to read metadata for any version of the API keys
path "shared/metadata/dev/square-api/" {

  capabilities = ["read"]
}
```

<Tabs>

<Tab heading="Available path prefixes">

@include 'policies/path-prefixes.mdx'

</Tab>

<Tab heading="Available permissions">

@include 'policies/policy-permissions.mdx'

</Tab>

</Tabs>

If you are unsure about the required permissions, use the Vault CLI to run a
command with placeholder data and the `-output-policy` flag against an existing
`kv` plugin to generate a minimal policy. 

<CodeBlockConfig highlight="2">

```shell-session
$ vault kv patch                  \
    -output-policy                \
    -mount <existing_mount_path>  \
    test-path                     \
    test=test
```

</CodeBlockConfig>

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault kv patch      \
    -output-policy    \
    -mount private    \
    test-path         \
    test=test

path "private/data/test-path" {
  capabilities = ["patch"]
}
```

</CodeBlockConfig>

## Step 3: Save the ACL policy

<Tabs>

<Tab heading="CLI" group="cli">

Use `vault policy write` to create a new ACL policy with the policy definition
file:

```shell-session
$ vault policy write <name> <path_to_policy_file>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ vault policy write "KV-access-policy" ./kv-policy.hcl
```

</CodeBlockConfig>

</Tab>

<Tab heading="GUI" group="gui">

@include 'gui-instructions/create-acl-policy.mdx'

- Provide a name for the policy and upload the policy definition file.

<Tip>

If you expect to modify policies with the Vault API, avoid spaces and special
characters in the policy name. The policy name becomes part of the API endpoint
path.

</Tip>

</Tab>

<Tab heading="API" group="api">

Escape your policy file and make a `POST` call to
[`/sys/policy/{policy_name}`](/vault/api-docs/system/policy#create-update-policy)
with your policy details:

```shell-session
$ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' <path_to_policy_file> |
  curl                                        \
    --request POST                            \
    --header "X-Vault-Token: ${VAULT_TOKEN}"  \
    "$(</dev/stdin)"                          \
    ${VAULT_ADDR}/v1/sys/policy/<policy_name>
```

For example:

<CodeBlockConfig hideClipboard="true">

```shell-session
$ jq -Rs '{ "policy": . | gsub("[\\r\\n\\t]"; "") }' ./kv-policy.hcl |
  curl                                          \
      --request POST                            \
      --header "X-Vault-Token: ${VAULT_TOKEN}"  \
      --data "$(</dev/stdin)"                   \
      ${VAULT_ADDR}/v1/sys/policy/kv-access | jq
```

</CodeBlockConfig>

`/sys/mounts/{plugin_mount_path}` does not return data on success.

</Tab>

</Tabs>



## Next steps 

- [Create an authentication mapping for the plugin](/vault/docs/concepts/policies#associating-policies)
